#!/usr/bin/env python
# -*- coding: utf8 -*-
# title       :
# description :
# author      :'ShenMeng'

from PySide import QtGui, QtCore
import maya.OpenMaya as om
import pymel.core as pmel
import math
from tder_maya import undoCmds, undoPmel

class DropDialog(QtGui.QDialog):
    def __init__(self, parent=QtGui.QApplication.activeWindow()):
        super(DropDialog, self).__init__(parent)
        from .pyuic.drop_form import Ui_dropForm
        self._ui = Ui_dropForm()
        self._ui.setupUi(self)
        self._ui.addGroundBtn.clicked.connect(self.on_add_ground_btn_clicked)
        self._ui.delGroundBtn.clicked.connect(self.on_del_ground_btn_clicked)
        self._ui.dropRunBtn.clicked.connect(self.on_drop_run_btn_clicked)
        self._ui.detailWidget.hide()

    def message_dialog(self, text):
        messageBox = QtGui.QMessageBox(self)
        messageBox.setWindowTitle(u'提示')
        messageBox.addButton('    ok    ', QtGui.QMessageBox.ActionRole)
        messageBox.setText(text)
        messageBox.exec_()

    def on_add_ground_btn_clicked(self):
        selObjList = [obj.name() for obj in pmel.ls(sl=1) if obj.getShape().type() == 'mesh']
        if not selObjList:
            return
        itemList = self.get_ground_list_widget_items()
        if itemList:
            for obj in selObjList:
                if obj not in itemList:
                    self._ui.groundListWidget.addItem(obj)
        else:
            self._ui.groundListWidget.addItems(selObjList)

    def on_del_ground_btn_clicked(self):
        currentRow = self._ui.groundListWidget.currentRow()
        self._ui.groundListWidget.takeItem(currentRow)

    @undoPmel
    def on_drop_run_btn_clicked(self):
        itemList = self.get_ground_list_widget_items()
        if not itemList:
            self.message_dialog(u'请先添加地面物体！')
            return
        selObjList = om.MSelectionList()
        om.MGlobal.getActiveSelectionList(selObjList)
        iterator = om.MItSelectionList(selObjList)
        dagPath = om.MDagPath()
        while(not iterator.isDone()):
            iterator.getDagPath(dagPath)
            fnTrans = om.MFnTransform(dagPath)
            objTrans = fnTrans.translation(4)
            objRotate = fnTrans.rotatePivot(4)
            hitPointList = []
            if self._ui.dropDirX.isChecked():
                temp = [objRotate.x, 0.0, 0.0, 1.0, 0.0, 0.0]
                direction = om.MFloatVector(-1.0, 0.0, 0.0)
            elif self._ui.dropDirY.isChecked():
                temp = [0.0, objRotate.y, 0.0, 0.0, 1.0, 0.0]
                direction = om.MFloatVector(0.0, -1.0, 0.0)
            elif self._ui.dropDirZ.isChecked():
                temp = [0.0, 0.0, objRotate.z, 0.0, 0.0, 1.0]
                direction = om.MFloatVector(0.0, 0.0, -1.0)
            for groundObj in itemList:
                target = self.get_target(groundObj, objRotate, direction)
                if target:
                    hitPointList.append(target[0])
            if hitPointList:
                if len(hitPointList) == 1:
                    point = hitPointList[0]
                else:
                    pointDistanceDict = {}
                    distanceList = []
                    for hitPoint in hitPointList:
                        distance = self.get_distance(objTrans, hitPoint)
                        distanceList.append(distance)
                    minIndex = distanceList.index(min(distanceList))
                    point = hitPointList[minIndex]

                fnTrans.setTranslation(om.MVector((objTrans.x - temp[0] + temp[-3] * point.x),
                                                  (objTrans.y - temp[1] + temp[-2] * point.y),
                                                  (objTrans.z - temp[2] + temp[-1] * point.z)), 4)
            iterator.next()

    def get_distance(self, source, target):
        distance = math.sqrt(
            math.pow((source.x - target.x), 2) +
            math.pow((source.y - target.y), 2) +
            math.pow((source.z - target.z), 2)
        )
        return distance

    def get_target(self, dagPathStr, point, direction):
        hitPoint = om.MFloatPoint()
        dagPath = self.get_dag_path(dagPathStr)
        fnMesh = om.MFnMesh(dagPath)
        hitStatus = fnMesh.closestIntersection(
            om.MFloatPoint(point.x, point.y, point.z),
            direction,
            None,
            None,
            True,
            om.MSpace.kWorld,
            10000.0,
            True,
            None,
            hitPoint,
            None,
            None,
            None,
            None,
            None
        )
        if hitStatus:
            return (hitPoint, )

    def get_dag_path(self, dagPathStr):
        selList = om.MSelectionList()
        dagPath = om.MDagPath()
        om.MGlobal.getSelectionListByName(dagPathStr, selList)
        selList.getDagPath(0, dagPath)
        return dagPath

    def get_ground_list_widget_items(self):
        count = self._ui.groundListWidget.count()
        itemList = []
        if not count:
            return
        for i in range(count):
            item = self._ui.groundListWidget.item(i)
            itemList.append(item.text())
        return itemList

